package com.gxa.luckin.sso.service.impl;

import com.gxa.luckin.core.exception.BusinessException;
import com.gxa.luckin.core.exception.MessageCode;
import com.gxa.luckin.core.pojo.User;
import com.gxa.luckin.core.utils.JsonUtils;
import com.gxa.luckin.sso.repository.SsoRepository;
import com.gxa.luckin.sso.service.SsoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service("ssoService")
public class SsoServiceImpl implements SsoService {

    @Resource
    RedisTemplate redisTemplate;

    @Resource
    SsoRepository ssoRepository;

    @Autowired
    HttpServletRequest request;

    private static final String LOGIN_TOKEN = "alibaba:";

    @Override
    public Map<String, String> login(String phone, String code) throws BusinessException {

        // 处理短信验证
        //1.获取redis服务器存储的验证码
        Object smsCode = redisTemplate.opsForValue().get(SmsServiceImpl.LOGIN_SMS + phone);

        //2.验证码失效的判断,如果为空则抛出异常
        if (StringUtils.isEmpty(smsCode)) {
            throw new BusinessException(MessageCode.LOGIN_SMS_EXPIRE);
        }

        //3.对验证码做校验, 如果不一致则抛出异常
        if (!code.equals(smsCode)) {
            throw new BusinessException(MessageCode.LOGIN_SMS_ERROR);
        }

        //校验完成, 从mysql数据库中查找用户信息
        // 使用JPA完成查询: 通过手机号
        User user = ssoRepository.findByPhone(phone);

        // 删除验证码
        //redisTemplate.delete(SmsServiceImpl.LOGIN_SMS+phone);

        //如果用户不存在, 则匿名注册,匿名格式: "用户:"+phone , 并指定用户状态
        if (user == null) {
            user = new User();
            user.setName("用户" + phone);
            user.setStatus(1);
            user.setPhone(phone);
            // 完成注册
            User save = ssoRepository.save(user);
        }

        // userbyPhone对象非空表示用户对象存在, 判断status
        if (user.getStatus() != 1) {
            throw new BusinessException(MessageCode.LOGIN_ERROR);
        }
        //判断如果用户存储redis中的token信息还在(没有过期)
        //只能从数据库中查询
        redisTemplate.delete(LOGIN_TOKEN + user.getToken());
        //生成token，存储登录信息(json),利用处理后的UUID
        String token = UUID.randomUUID().toString().replace("-", "");
        //把token添加到对象中
        user.setToken(token);
        //用户状态
        user.setLastLoginTime(new Date());
        // 处理token


        //用户的ip(beanFactory)
//        user.setIpAddress(request.getRemoteAddr());
        User save = ssoRepository.save(user);
        //处理token:密钥组合
//        value:放经过json转换的用户信息
        String key = LOGIN_TOKEN + token;
        String value = JsonUtils.objectToJson(user);
        redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);

        Map<String, String> result = new HashMap<>();
        result.put("token", token);
//        return null;
        return result;
    }

    @Override
    public User validateToken(String token) throws BusinessException {
        String key = LOGIN_TOKEN + token;
        //从redis中获取token对应的key
        Object tokenKey = redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(tokenKey)) {
            throw new BusinessException(MessageCode.TOKEN_ERROR);
        }
        return JsonUtils.jsonToObject(tokenKey.toString(),User.class);
    }
}